package com.wish.util;

import com.wish.dto.WebCommonInfo;
import com.wish.enums.DeviceType;
import com.wish.enums.UserType;
import org.springframework.context.MessageSource;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.LocaleResolver;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Locale;
import java.util.regex.Pattern;

/**
 * Miscellaneous utilities for web applications.
 * @author L.cm
 */
public class WebUtils extends org.springframework.web.util.WebUtils {
    //移动设备Agent
    private static final String phoneAgentReg =
    	"\\bNokia|SAMSUNG|MIDP-2|CLDC1.1|SymbianOS|MAUI|UNTRUSTED/1.0"
	    +"|Windows CE|iPhone|iPad|Android|BlackBerry|UCWEB|ucweb|BREW|J2ME|YULONG|YuLong|COOLPAD|TIANYU|TY-"
	    +"|K-Touch|Haier|DOPOD|Lenovo|LENOVO|HUAQIN|AIGO-|CTC/1.0"
	    +"|CTC/2.0|CMCC|DAXIAN|MOT-|SonyEricsson|GIONEE|HTC|ZTE|HUAWEI|webOS|GoBrowser|IEMobile|WAP2.0\\b";
    private static final String tableAgentReg =
		"\\b(ipad|tablet|(Nexus 7)|up.browser"
        +"|[1-4][0-9]{2}x[1-4][0-9]{2})\\b";

    //移动设备正则匹配：手机端、平板
    static Pattern phoneAgentPat = Pattern.compile(phoneAgentReg, Pattern.CASE_INSENSITIVE);
    static Pattern tableAgentePat = Pattern.compile(tableAgentReg, Pattern.CASE_INSENSITIVE);

    //线程本地变量
	private static final ThreadLocal<WebCommonInfo> webInfo = new ThreadLocal<WebCommonInfo>();

	/**
	 * 判断是否ajax请求
	 * spring ajax 返回含有 ResponseBody 或者 RestController注解
	 * @param handlerMethod HandlerMethod
	 * @return 是否ajax请求
	 */
	public static boolean isAjax(HandlerMethod handlerMethod) {
		ResponseBody responseBody = handlerMethod.getMethodAnnotation(ResponseBody.class);
		if (null != responseBody) {
			return true;
		}
		// 获取类上面的Annotation，可能包含组合注解，故采用spring的工具类
		Class<?> beanType = handlerMethod.getBeanType();
		responseBody = AnnotationUtils.getAnnotation(beanType, ResponseBody.class);
		if (null != responseBody) {
			return true;
		}
		return false;
	}

	/**
	 * 读取cookie
	 * @param
	 * @param
	 * @return
	 */
	public static String getCookieValue(HttpServletRequest request, String name) {
		Cookie cookie = getCookie(request, name);
		return cookie != null ? cookie.getValue() : null;
	}

	/**
	 * 清除 某个指定的cookie
	 * @param response
	 * @param key
	 */
	public static void removeCookie(HttpServletResponse response, String key) {
		setCookie(response, key, null, 0);
	}

	/**
	 * 设置cookie
	 * @param response
	 * @param name
	 * @param value
	 * @param maxAgeInSeconds
	 */
	public static void setCookie(HttpServletResponse response, String name, String value, int maxAgeInSeconds) {
		Cookie cookie = new Cookie(name, value);
		cookie.setPath("/");
		cookie.setMaxAge(maxAgeInSeconds);
		cookie.setHttpOnly(true);
		response.addCookie(cookie);
	}


	public static boolean isMobileAgent(String agent) {
		if (agent == null) {
			return false;
		}
		return phoneAgentPat.matcher(agent).find();
	}

	public static void setDeviceType(DeviceType device) {
		getWebCommonInfo().setDeviceType(device);
	}

	public static DeviceType getDeviceType() {
		return getWebCommonInfo().getDeviceType();
	}

	public static void setRequest(HttpServletRequest request) {
		getWebCommonInfo().setRequest(request);
	}

	public static HttpServletRequest getRequest() {
		return getWebCommonInfo().getRequest();
	}

	public static void setUserType(UserType userType) {
		getWebCommonInfo().setUserType(userType);
	}

	public static UserType getUserType() {
		return getWebCommonInfo().getUserType();
	}

	public static WebCommonInfo getWebCommonInfo() {
		WebCommonInfo info = webInfo.get();
		if (info == null) {
			info = new WebCommonInfo();
			webInfo.set(info);
		}

		return info;
	}

	/**
	 * 得到网站URL的根URL，
	 * 例如：http://www.baidu.com    http://127.0.0.1:8080/test
	 * @return
	 */
	public static String getWebBaseUrl() {
		HttpServletRequest request = getRequest();

		String port;
		if ("http".equals(request.getScheme().toLowerCase())) {
			if (request.getServerPort() == 80) {
				port = "";
			}
			else {
				port = ":" + request.getServerPort();
			}
		}
		else if ("https".equals(request.getScheme().toLowerCase())) {
			if (request.getServerPort() == 443) {
				port = "";
			}
			else {
				port = ":" + request.getServerPort();
			}
		}
		else {
			port = ":" + request.getServerPort();
		}

		return request.getScheme() + "://" + request.getServerName() + port + request.getContextPath();
	}

	/**
	 * 通过相对网址拼接处完整的URL
	 * @param relativeUrl  例如：/Api/auctionItem
	 * @return 完整URL，例如：http://localhost:8008/test/Api/auctionItem
	 */
	public static String getFullUrl(String relativeUrl) {
		if (relativeUrl.charAt(0) == '/') {
			return getWebBaseUrl() + relativeUrl;
		}
		else {
			return getWebBaseUrl() + "/" + relativeUrl;
		}
	}

	/**
	 * 通过完整地址取得站内的相对地址
	 * @param fullUrl  例如：http://localhost:8008/test/Api/auctionItem
	 * @return 相对URL，例如：/Api/auctionItem
	 */
	public static String getRelativeUrl(String fullUrl) {
		HttpServletRequest request = getRequest();
		String context = request.getContextPath();
		int idx = fullUrl.indexOf("://");
		if (idx == -1) {
			idx = 0;
		} else {
			idx += 4;
		}
		idx = fullUrl.indexOf('/', idx) + context.length();
		return fullUrl.substring(idx);
	}

	public static String getRequestDomain(HttpServletRequest request) {
		String url = request.getRequestURL().toString();
		int idx1 = url.indexOf("//");
		int idx2 = url.indexOf('/', idx1+2);
		int idx3 = url.indexOf(':', idx1+2);
		if (idx3 > 0 && idx3 < idx2) {
			return url.substring(idx1+2, idx3);
		}
		else {
			return url.substring(idx1+2, idx2);
		}
	}

    public static String getI18nMessage(String msgCode, String defaultMsg) {
    	Locale locale = SpringUtils.getBean(LocaleResolver.class).resolveLocale(WebUtils.getRequest());
    	return  SpringUtils.getBean(MessageSource.class).getMessage(msgCode, null, defaultMsg, locale);
    }

    public static String getI18nMessage(String msgCode, Object[] args, String defaultMsg) {
    	Locale locale = SpringUtils.getBean(LocaleResolver.class).resolveLocale(WebUtils.getRequest());
    	return  SpringUtils.getBean(MessageSource.class).getMessage(msgCode, args, defaultMsg, locale);
    }

    public static String getI18nMessage(String msgCode, Object[] args) {
    	Locale locale = SpringUtils.getBean(LocaleResolver.class).resolveLocale(WebUtils.getRequest());
    	return  SpringUtils.getBean(MessageSource.class).getMessage(msgCode, args, locale);
    }

    public static String getI18nMessage(String msgCode, Object[] args, Locale locale) {
    	return  SpringUtils.getBean(MessageSource.class).getMessage(msgCode, args, locale);
    }
}
